using ERPBackend.Data;
using ERPBackend.Models;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Linq;
using System;

namespace ERPBackend.Services
{
    public class PurchaseStockInService : IPurchaseStockInService
    {
        private readonly ApplicationDbContext _context;
        private readonly IInventoryService _inventoryService;

        public PurchaseStockInService(ApplicationDbContext context, IInventoryService inventoryService)
        {
            _context = context ?? throw new ArgumentNullException(nameof(context));
            _inventoryService = inventoryService ?? throw new ArgumentNullException(nameof(inventoryService));
        }

        public async Task<IEnumerable<PurchaseStockIn>> GetAllPurchaseStockInsAsync()
        {
            return await _context.PurchaseStockIns
                
                .Include(psi => psi.Warehouse)
                .Include(psi => psi.PurchaseStockInItems)
                    .ThenInclude(psii => psii.Material)
                .ToListAsync() ?? Enumerable.Empty<PurchaseStockIn>();
        }

        public async Task<int> GetTotalPurchaseStockInsAsync()
        {
            return await _context.PurchaseStockIns.CountAsync();
        }

        public async Task<IEnumerable<PurchaseStockIn>> GetPurchaseStockInsPagedAsync(int page, int pageSize)
        {
            int skip = (page - 1) * pageSize;
            return await _context.PurchaseStockIns

                .Include(psi => psi.Warehouse)
                .OrderByDescending(psi => psi.CreatedTime)
                .Skip(skip)
                .Take(pageSize)
                .ToListAsync() ?? Enumerable.Empty<PurchaseStockIn>();
        }

        public async Task<PurchaseStockIn?> GetPurchaseStockInByIdAsync(int id)
        {
            return await _context.PurchaseStockIns

                .Include(psi => psi.Warehouse)
                .Include(psi => psi.PurchaseStockInItems)
                    .ThenInclude(psii => psii.Material)
                .FirstOrDefaultAsync(psi => psi.Id == id);
        }

        public async Task<PurchaseStockIn?> GetPurchaseStockInByCodeAsync(string stockInCode)
        {
            return await _context.PurchaseStockIns

                .Include(psi => psi.Warehouse)
                .Include(psi => psi.PurchaseStockInItems)
                    .ThenInclude(psii => psii.Material)
                .FirstOrDefaultAsync(psi => psi.StockInCode == stockInCode);
        }

        public async Task<PurchaseStockIn> CreatePurchaseStockInAsync(PurchaseStockIn purchaseStockIn)
        {
            // 检查入库单编码是否已存在
            var existingStockIn = await _context.PurchaseStockIns
                .FirstOrDefaultAsync(psi => psi.StockInCode == purchaseStockIn.StockInCode);
            if (existingStockIn != null)
            {
                throw new ArgumentException("入库单编码已存在");
            }

            // 检查采购订单是否存在
            var purchaseOrder = await _context.PurchaseOrders.FindAsync(purchaseStockIn.PurchaseOrderId);
            if (purchaseOrder == null)
            {
                throw new ArgumentException("关联的采购订单不存在");
            }

            // 检查供应商是否存在
            var supplier = await _context.Suppliers.FindAsync(purchaseStockIn.SupplierId);
            if (supplier == null)
            {
                throw new ArgumentException("供应商不存在");
            }

            // 检查仓库是否存在
            var warehouse = await _context.Warehouses.FindAsync(purchaseStockIn.WarehouseId);
            if (warehouse == null)
            {
                throw new ArgumentException("仓库不存在");
            }

            // 设置默认状态为待审核
            purchaseStockIn.Status = "待审核";
            purchaseStockIn.CreatedTime = DateTime.Now;
            purchaseStockIn.UpdatedTime = DateTime.Now;

            // 计算总数量和总金额
            if (purchaseStockIn.PurchaseStockInItems != null && purchaseStockIn.PurchaseStockInItems.Any())
            {
                purchaseStockIn.TotalQuantity = purchaseStockIn.PurchaseStockInItems.Sum(psii => psii.StockInQuantity);
                purchaseStockIn.TotalAmount = purchaseStockIn.PurchaseStockInItems.Sum(psii => psii.Amount);
            }
            else
            {
                purchaseStockIn.TotalQuantity = 0;
                purchaseStockIn.TotalAmount = 0;
            }

            _context.PurchaseStockIns.Add(purchaseStockIn);
            await _context.SaveChangesAsync();
            return purchaseStockIn;
        }

        public async Task<bool> UpdatePurchaseStockInAsync(PurchaseStockIn purchaseStockIn)
        {
            // 检查入库单是否存在
            var existingStockIn = await _context.PurchaseStockIns.FindAsync(purchaseStockIn.Id);
            if (existingStockIn == null)
            {
                return false;
            }

            // 检查入库单编码是否已被其他入库单使用
            if (existingStockIn.StockInCode != purchaseStockIn.StockInCode &&
                await _context.PurchaseStockIns.AnyAsync(psi => psi.StockInCode == purchaseStockIn.StockInCode))
            {
                throw new ArgumentException("入库单编码已被使用");
            }

            // 检查采购订单是否存在
            if (purchaseStockIn.PurchaseOrderId != existingStockIn.PurchaseOrderId)
            {
                var purchaseOrder = await _context.PurchaseOrders.FindAsync(purchaseStockIn.PurchaseOrderId);
                if (purchaseOrder == null)
                {
                    throw new ArgumentException("关联的采购订单不存在");
                }
            }

            // 检查供应商是否存在
            if (purchaseStockIn.SupplierId != existingStockIn.SupplierId)
            {
                var supplier = await _context.Suppliers.FindAsync(purchaseStockIn.SupplierId);
                if (supplier == null)
                {
                    throw new ArgumentException("供应商不存在");
                }
            }

            // 检查仓库是否存在
            if (purchaseStockIn.WarehouseId != existingStockIn.WarehouseId)
            {
                var warehouse = await _context.Warehouses.FindAsync(purchaseStockIn.WarehouseId);
                if (warehouse == null)
                {
                    throw new ArgumentException("仓库不存在");
                }
            }

            // 更新属性
            existingStockIn.StockInCode = purchaseStockIn.StockInCode;
            existingStockIn.PurchaseOrderId = purchaseStockIn.PurchaseOrderId;
            existingStockIn.SupplierId = purchaseStockIn.SupplierId;
            existingStockIn.StockInDate = purchaseStockIn.StockInDate;
            existingStockIn.WarehouseId = purchaseStockIn.WarehouseId;
            existingStockIn.Status = purchaseStockIn.Status;
            existingStockIn.TotalQuantity = purchaseStockIn.TotalQuantity;
            existingStockIn.TotalAmount = purchaseStockIn.TotalAmount;
            existingStockIn.Remark = purchaseStockIn.Remark;
            existingStockIn.UpdatedBy = purchaseStockIn.UpdatedBy;
            existingStockIn.UpdatedTime = DateTime.Now;

            _context.Entry(existingStockIn).State = EntityState.Modified;
            return await _context.SaveChangesAsync() > 0;
        }

        public async Task<bool> DeletePurchaseStockInAsync(int id)
        {
            var purchaseStockIn = await _context.PurchaseStockIns.FindAsync(id);
            if (purchaseStockIn == null)
            {
                return false;
            }

            // 检查是否有相关的明细
            var hasItems = await _context.PurchaseStockInItems
                .AnyAsync(psii => psii.PurchaseStockInId == id);
            if (hasItems)
            {
                // 先删除明细
                var items = await _context.PurchaseStockInItems
                    .Where(psii => psii.PurchaseStockInId == id)
                    .ToListAsync();
                _context.PurchaseStockInItems.RemoveRange(items);
            }

            _context.PurchaseStockIns.Remove(purchaseStockIn);
            return await _context.SaveChangesAsync() > 0;
        }

        public async Task<bool> ChangePurchaseStockInStatusAsync(int id, string status)
        {
            var purchaseStockIn = await _context.PurchaseStockIns.FindAsync(id);
            if (purchaseStockIn == null)
            {
                return false;
            }

            purchaseStockIn.Status = status;
            purchaseStockIn.UpdatedTime = DateTime.Now;

            _context.Entry(purchaseStockIn).State = EntityState.Modified;
            return await _context.SaveChangesAsync() > 0;
        }

        public async Task<bool> ApprovePurchaseStockInAsync(int id, int approverId, string? comments)
        {
            var purchaseStockIn = await _context.PurchaseStockIns.FindAsync(id);
            if (purchaseStockIn == null)
            {
                return false;
            }

            // 检查状态是否为待审核
            if (purchaseStockIn.Status != "待审核")
            {
                throw new InvalidOperationException("只有待审核的入库单才能进行审核");
            }

            // 更新审核状态
            purchaseStockIn.Status = "已审核";
            purchaseStockIn.ApprovedBy = approverId;
            purchaseStockIn.ApprovedTime = DateTime.Now;
            purchaseStockIn.Remark = comments;
            purchaseStockIn.UpdatedTime = DateTime.Now;

            // 审核通过后，更新库存数量
            if (purchaseStockIn.PurchaseStockInItems != null && purchaseStockIn.PurchaseStockInItems.Any())
            {
                foreach (var item in purchaseStockIn.PurchaseStockInItems)
                {
                    // 调用库存服务更新库存
                    await _inventoryService.UpdateInventoryQuantityAsync(
                        item.MaterialId,
                        purchaseStockIn.WarehouseId,
                        item.StockInQuantity,
                        0,
                        "采购入库",
                        0
                    );
                }
            }

            _context.Entry(purchaseStockIn).State = EntityState.Modified;
            return await _context.SaveChangesAsync() > 0;
        }
    }
}